package system.util;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Base64;

import system.activity.MainListener;
import user.view.Controls;

public class HistoryReader
{

	MainListener listener;

	public HistoryReader(final MainListener listener)
	{
		this.listener = listener;
	}

	public void readFile(File file) throws FileNotFoundException
	{
		try {
			FileInputStream fin = new FileInputStream(file);
			byte[] coded = new byte[fin.available()];
			fin.read(coded);
			byte[] input = new byte[coded.length];
			for (int i = 0; i < coded.length; i++) {
				input[i]=coded[coded.length-i-1];
			}
			String fileString = new String(Base64.decodeBase64(input));
			Scanner sc = new Scanner(fileString);
			Pattern p = Pattern.compile("([\\w]+[.]?[\\w]+[;])+");
			ArrayList<String> params = new ArrayList<String>();
			while (sc.hasNextLine()) {
				String currentLine = sc.nextLine();
				Matcher m = p.matcher(currentLine);
				if (m.find()) {
					String[] words = currentLine.split(";");
					for (int i = 0; i < words.length; i++) {
						params.add(words[i]);
					}
					createInstance(params);
				} else {
					listener.showErrorMessage("Некорректный файл. Описание ДОЭ не найдено.");
				}
			}
		} catch (IOException ex) {
			ex.printStackTrace();
			listener.showErrorMessage("Ошибка при чтении ДОЭ");
		}
	}

	public static void saveDOE(String doeDescription, String reportFileFolder)
	{
		try {
			FileOutputStream fileOut = new FileOutputStream(reportFileFolder.endsWith(".doe") ? reportFileFolder : reportFileFolder + ".doe");
			ByteArrayOutputStream writer = new ByteArrayOutputStream();
			// encoding byte array into base 64
			byte[] coded = Base64.encodeBase64(doeDescription.getBytes());
			byte[] result = new byte[coded.length];
			for (int i = 0; i < coded.length; i++) {
				result[i]=coded[coded.length-i-1];
			}
			writer.write(result);
			writer.writeTo(fileOut);
			writer.close();
			fileOut.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public Controls createInstance(ArrayList<String> params)
	{
		try {
			Class c = Class.forName(params.get(0));
			Class[] parameterTypes = new Class[2];
			parameterTypes[0] = MainListener.class;
			parameterTypes[1] = ArrayList.class;
			ArrayList<String> list = new ArrayList<String>();
			Constructor constructor = c.getConstructor(parameterTypes);
			Object[] args = new Object[2];
			args[0] = listener;
			for (int i = 1; i < params.size(); i++) {
				list.add(params.get(i));
			}
			args[1] = list;
			Object o = constructor.newInstance(args);
			return (Controls) o;
		} catch (Exception ex) {
			ex.printStackTrace();
		}
		return null;
	}
}
